# Copyright (C) 2009,2010,2011,2012  Marco Restelli
#
# This file is part of:
#   FEMilaro -- Finite Element Method toolkit
#
# FEMilaro is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# FEMilaro is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with FEMilaro; If not, see <http://www.gnu.org/licenses/>.
#
# author: Marco Restelli                   <marco.restelli@gmail.com>
#
# List of the object files of the present folder
OBJ= mod_linsolver_base.o \
     mod_iterativesolvers_base.o \
     mod_gmres.o \
     $(MOD_MUMPS_ITF).o \
     mod_umfintf.o \
     $(UMF4_f77WRAPPER) \
     $(MOD_UMFPACK).o \
     $(MOD_PASTIX_ITF).o \
     mod_linsolver.o \
     mod_newton.o
# These are the modules that are meant to be USEd by the library users
LIBRARY_MOD_FILES= mod_linsolver.mod \
     mod_newton.mod
OBJ_LINSTEST= linsolver_test.o \
     $(OBJ)

# General settings -----------------------------------

PWD:=$(shell pwd)
BUILDDIR:=$(BUILDDIR)/fml_linear_solvers

LIBS:=-lfml_general_utilities $(LIBS)
LDFLAGS:=$(LDFLAGS) -L$(LIBDIR)

# VPATH includes:
#   PWD for the source files (included by default)
#   BUILDDIR for the .o prerequisites
#   LIBDIR for the libfml_general_utilities.a library
#   BINDIR for the final executable
VPATH:=$(BUILDDIR) $(LIBDIR) $(BINDIR)

# clear unfinished targets
.DELETE_ON_ERROR:
# define the phony targets
.PHONY: clean

# check what to do with MUMPS
# 
# To see why we need to remove the alternate file, consider the
# following situation:
# a) compile with USING_MUMPS=Yes -> generate mod_mumpsintf.o
# b) change to    USING_MUMPS=No -> generate mod_mumpsintf_dummy.o
# c) change back to USING_MUMPS=Yes -> mod_mumpsintf.o is still
#   present because of a), so everything seems up to date, but the
#   library libfml_linear_solvers.a links mod_mumpsintf_dummy.o, which
#   is not what has been required.
# So, to avoid this problem, we ensure that at most *one* object for
# mod_mumpsintf is present.
ifeq ($(USING_MUMPS),Yes)
  MOD_MUMPS_ITF=mod_mumpsintf
  XXX:=$(shell $(RM) $(BUILDDIR)/mod_mumpsintf_dummy.o)
else
  MOD_MUMPS_ITF=mod_mumpsintf_dummy
  XXX:=$(shell $(RM) $(BUILDDIR)/mod_mumpsintf.o)
endif

# check waht to do with UMFpack
ifeq ($(USING_UMFPACK),Yes)
  MOD_UMFPACK=mod_umfpack
  UMF4_f77WRAPPER=umf4_f77wrapper.o
  XXX:=$(shell $(RM) $(BUILDDIR)/mod_umfpack_dummy.o)
else
  MOD_UMFPACK=mod_umfpack_dummy
  UMF4_f77WRAPPER=
  XXX:=$(shell $(RM) $(BUILDDIR)/mod_umfpack.o $(BUILDDIR)/umf4_f77wrapper.o)
endif

# check waht to do with PaStiX
ifeq ($(USING_PASTIX),Yes)
  MOD_PASTIX_ITF=mod_pastixintf
  XXX:=$(shell $(RM) $(BUILDDIR)/mod_pastixintf_dummy.o)
else
  MOD_PASTIX_ITF=mod_pastixintf_dummy
  XXX:=$(shell $(RM) $(BUILDDIR)/mod_pastixintf.o)
endif


# Main targets ---------------------------------------

libfml_linear_solvers.a: $(OBJ)
	cd $(BUILDDIR) && $(AR) -r $(LIBDIR)/libfml_linear_solvers.a $(OBJ)
	for mod in $(LIBRARY_MOD_FILES);     \
        do                                   \
          cp $(BUILDDIR)/$${mod} $(LIBDIR)/; \
        done

linsolver-test: $(OBJ_LINSTEST)
	cd $(BUILDDIR) && \
	  $(LD) $(LDFLAGS) $(OBJ_LINSTEST) $(LIBS) -o $(BINDIR)/linsolver-test

# General rule: all the .o depend on the libfml_general_utilities library
%.o: %.f90 libfml_general_utilities.a
	cd $(BUILDDIR) && \
	  $(FC) $(FFLAGS) $(MODFLAG)$(LIBDIR) -c $(PWD)/$<

clean:
	$(RM) $(BUILDDIR)/*.o $(BUILDDIR)/*.ilo $(BUILDDIR)/*.mod \
	  $(LIBDIR)/libfml_linear_solvers.a $(BINDIR)/linsolver-test
	for mod in $(LIBRARY_MOD_FILES); \
        do                               \
          $(RM) $(LIBDIR)/$${mod};       \
        done

# Specific dependencies: because of USE directives ---
# Notice: here we list only the prerequisites which are not already
# included in the libfml_general_utilities.a library, which is a
# prerequisite of all the .o files listed in this Makefile

linsolver_test.o: \
   mod_linsolver.o

mod_iterativesolvers_base.o: \
   mod_linsolver_base.o

mod_gmres.o: \
   mod_iterativesolvers_base.o

# We need a specific rule because there is an additional include
mod_mumpsintf.o: mod_mumpsintf.f90
mod_mumpsintf_dummy.o: mod_mumpsintf_dummy.f90
mod_mumpsintf.o mod_mumpsintf_dummy.o: \
  mod_linsolver_base.o
	cd $(BUILDDIR) && $(FC) $(FFLAGS) $(MODFLAG)$(LIBDIR) \
          $(MUMPS_INCLUDE) -c $(PWD)/$(subst .o,.f90,$@)

# We need a specific rule because there is an additional include
mod_pastixintf.o: mod_pastixintf.f90
mod_pastixintf_dummy.o: mod_pastixintf_dummy.f90
mod_pastixintf.o mod_pastixintf_dummy.o: \
  mod_linsolver_base.o
	cd $(BUILDDIR) && $(FC) $(FFLAGS) $(MODFLAG)$(LIBDIR) \
          $(PASTIX_INCLUDE) -c $(PWD)/$(subst .o,.f90,$@)

# CFLAGS should be set in the main Makefile (it is then exported here)
umf4_f77wrapper.o: umf4_f77wrapper.c
	cd $(BUILDDIR) && \
          $(CC) $(CFLAGS) $(CC_INCLUDE) -c $(PWD)/umf4_f77wrapper.c

# Filter some variables (see mod_mpi_utils in fml_general_utilities)
mod_umfpack.o: mod_umfpack.f90
	cd $(BUILDDIR) && $(FC) $(filter-out \
	  -std=f2003 \
	 , $(FFLAGS)) $(MODFLAG)$(LIBDIR) -c $(PWD)/$<

mod_umfintf.o: \
  $(MOD_UMFPACK).o \
  mod_linsolver_base.o

mod_linsolver.o: \
   mod_linsolver_base.o \
   mod_iterativesolvers_base.o \
   mod_gmres.o \
   $(MOD_MUMPS_ITF).o \
   $(MOD_PASTIX_ITF).o \
   mod_umfintf.o
   
